/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pkg1;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Rectangle2D;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

/**
 * Instances of this class represent Bed objects in the
 * domain model.
 * @author Nick
 */
public class Bed extends JPanel{
    // Whether or not the bed is currently empty.
    // If it is empty it does not necessarily mean that it is also clean.
    private boolean available;
    // Whether or not the bed is cleaned.
    private boolean cleaned;
    // Whether or not the bed is for critical patients only.
    private boolean criticalCare;
    // Whether or not the bed is in a critical care facility and is for normal patients.
    private boolean normalBedInSpecialCare;
    // the unique ID of the bed.
    private int id;
    // the patient which currently occupies the bed.
    private Patient patient = null;
    // The context for the whole program.
    private Context context;
    //Whether or not a bed is in layout mode.
    private boolean inLayoutMode = false;
    //Constructor
    public Bed(boolean available, boolean cleaned, boolean specialCare, boolean normalBedInSpecialCare, int id) {
        this.available = available;
        this.cleaned = cleaned;
        this.criticalCare = specialCare;
        this.id = id;
        this.normalBedInSpecialCare = normalBedInSpecialCare;
        context = Context.getContext();
        this.addMouseListener(new MouseHandler1());
        updateBackgroundColor();
        
    }

    /**
     * whether or not a bed is available
     * @return the available
     */
    public boolean isAvailable() {
        return available;
    }

    /**
     * sets the bed's availability
     * @param available the available to set
     */
    public void setAvailable(boolean available) {
        this.available = available;
        updateBackgroundColor();
    }

    /**
     * returns the beds clean state
     * @return the cleaned
     */
    public boolean isCleaned() {
        return cleaned;
    }

    /**
     * sets the beds clean state
     * @param cleaned the cleaned to set
     */
    private void setCleaned(boolean cleaned) {
        this.cleaned = cleaned;
        updateBackgroundColor();
    }

    /**
     * @return the specialCare type
     */
    public boolean isCriticalCare() {
        return criticalCare;
    }
    
    /**
     * sets the critical care type
     * @param isCriticalCare 
     */
    public void setCriticalCare(boolean isCriticalCare) {
        criticalCare = isCriticalCare;
        updateBackgroundColor();
    }

    /**
     * @return the id
     */
    public int getId() {
        return id;
    }
    
    // Whether or not a point overlaps the current panel.
    public boolean overlaps(Point p) {
        if(this.contains(p)) {
            return true;
        }
        return false;
    }
    
    //Assigns a patient to the bed.
    public boolean assignPatient(Patient p) {
        if(getPatient() == null) {
            patient = p;
            p.setBedId(getId());
            setAvailable(false);
            setCleaned(false);
            context.getFloor(this).setChanged(true);
            return true;
        }
        else 
            return false;
    }

    //Dissmisses a patient from the bed.
    public Patient dismissPatient() {
        if(getPatient() == null) {
            return null;
        }
        Patient tmpPatient = getPatient();
        setAvailable(true);
        setCleaned(false);
        patient = null;
        context.getFloor(this).setChanged(true);
        return tmpPatient;
    }
    
    //Cleans the bed.
    public void clean() {
        if(getPatient() == null) {
            setCleaned(true);
            context.getFloor(this).setChanged(true);
        }
    }
    
    //Updates the background color of the bed based on
    //availability, cleanliness, and type.
    private void updateBackgroundColor() {
        if(available && cleaned && !criticalCare) {
            setBackground(Color.green);
            return;
        }
        else if(available && cleaned && criticalCare) {
            setBackground(Color.pink);
            return;
        }
        else if(available && !cleaned) {
            setBackground(Color.yellow);
        }
        else {
            setBackground(Color.red);
        }
    }

    /**
     * @return the patient
     */
    public Patient getPatient() {
        return patient;
    }
    
    // returns a string representing the bed based on its ID.
    public String toString() {
        if(id < 100) {
            return id + " (" + context.getFloor(this).getId() + ")";
        }
        if(id == 100) {
            return "A" + " (" + context.getFloor(this).getId() + ")";
        }
        if(id == 101) {
            return "B" + " (" + context.getFloor(this).getId() + ")";
        }
        return "C" + " (" + context.getFloor(this).getId() + ")";
    }

    /**
     * @return the normalBedInSpecialCare
     */
    public boolean isNormalBedInSpecialCare() {
        return normalBedInSpecialCare;
    }
    
    // if the bed is occupied, opens up a bedinformation form.
    // if the bed isn't occupied and isn't clean, allows user to clean bed.
    // if the bed is clean and vacant, opens the admitpatient form.
    private class MouseHandler1 extends MouseAdapter {
      public void mouseClicked(MouseEvent event) {
         if(!(inLayoutMode)) {
             Point p = (event.getPoint());
             if (overlaps(p) && Bed.this.getPatient() != null) {
                 Doctor doctor = context.getFloor(Bed.this).getDoctor(Bed.this.getPatient());
                 Nurse nurse = context.getFloor(Bed.this).getNurse(Bed.this.getPatient());
                 BedInformation info = new BedInformation(Bed.this, Bed.this.getPatient(), doctor.getName(), nurse.getName());
                 info.setVisible(true);
             }
             else if(overlaps(p) && Bed.this.available && Bed.this.cleaned) {
                 AdmitPatient window = new AdmitPatient(Bed.this);
                 window.setVisible(true);
             }
             else {
                 // cancel = 2
                 // no = 1
                 // yes  = 0
                 if(JOptionPane.showConfirmDialog(SwingUtilities.getWindowAncestor( Bed.this ), "Set room to cleaned?") == 0) {
                     clean();
                 }
             }
         }
      }
    }
    
    /*
     * creates a string that contains all the information needed for saving purposes
     */
    public String getSaveString() {
        String saveString = "";
        saveString += "Available:" + available + ",";
        saveString += "Cleaned:" + cleaned + ",";
        saveString += "SpecialCare:" + criticalCare + ",";
        saveString += "normalBedInSpecialCare:" + normalBedInSpecialCare  + ",";
        saveString += "visible:" + this.isVisible() + ",";
        saveString += "id:" + id;
        return saveString;
    }
    
    /*
     * sets whether or not a bed is in layout mode.
     */
    public void setLayoutMode(boolean inLayoutMode) {
        this.inLayoutMode = inLayoutMode;
    }
}
